
#ifndef __ZMALLOC_H
#define __ZMALLOC_H

#include <sys/types.h>

/* Double expansion needed for stringification of macro values. */
#define __xstr(s) __str(s)
#define __str(s) #s

#if defined(USE_TCMALLOC)
#define ZMALLOC_LIB ("tcmalloc-" __xstr(TC_VERSION_MAJOR) "." __xstr(TC_VERSION_MINOR))
#include <google/tcmalloc.h>
#if (TC_VERSION_MAJOR == 1 && TC_VERSION_MINOR >= 6) || (TC_VERSION_MAJOR > 1)
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) tc_malloc_size(p)
#else
#error "Newer version of tcmalloc required"
#endif

#elif defined(USE_JEMALLOC)
#define ZMALLOC_LIB ("jemalloc-" __xstr(JEMALLOC_VERSION_MAJOR) "." __xstr(JEMALLOC_VERSION_MINOR) "." __xstr(JEMALLOC_VERSION_BUGFIX))
#include <jemalloc/jemalloc.h>
#if (JEMALLOC_VERSION_MAJOR == 2 && JEMALLOC_VERSION_MINOR >= 1) || (JEMALLOC_VERSION_MAJOR > 2)
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) je_malloc_usable_size(p)
#else
#error "Newer version of jemalloc required"
#endif

#elif defined(__APPLE__)
#include <malloc/malloc.h>
#define HAVE_MALLOC_SIZE 1
#define zmalloc_size(p) malloc_size(p)
#endif

#ifndef ZMALLOC_LIB
#define ZMALLOC_LIB "libc"
#endif

void *zmalloc( size_t size );
void *zcalloc( size_t size );
void *zrealloc( void *ptr , size_t size );
void zfree( void *ptr );
char *zstrdup( const char *s );
size_t zmalloc_used_memory( void );
void zmalloc_enable_thread_safeness( void );
void zmalloc_set_oom_handler( void (*oom_handler)( size_t ) );
float zmalloc_get_fragmentation_ratio( size_t rss );
size_t zmalloc_get_rss( void );
size_t zmalloc_get_private_dirty( void );
size_t zmalloc_get_smap_bytes_by_field( char *field );
void zlibc_free( void *ptr );

#ifndef HAVE_MALLOC_SIZE
size_t zmalloc_size( void *ptr );
#endif

#endif /* __ZMALLOC_H */
